using System;
using System.Linq;
using System.Web.Mvc;
using EPiServer.Common;
using EPiServer.Common.Comments;
using EPiServer.Community.Blog;
using JoelAbrahamsson.BlogExtensions;
using JoelAbrahamsson.Web.Common;

namespace JoelAbrahamsson.Web.Controllers
{
    public class EntryController : Controller 
    {
        private ExtendedBlogHandlerFacade _blogHandlerFacade;
        private ICommentValidator[] _commentValidators;
        private ICommentAddedNotifier[] _commentAddedNotifiers;

        public EntryController(ExtendedBlogHandlerFacade blogHandlerFacade, 
            ICommentValidator[] commentValidators, 
            ICommentAddedNotifier[] commentAddedNotifiers)
        {
            _blogHandlerFacade = blogHandlerFacade;
            _commentValidators = commentValidators;
            _commentAddedNotifiers = commentAddedNotifiers;
        }

        public ActionResult Index(Entry entry)
        {
            return View(entry);
        }

        public ActionResult WlwLayout()
        {
            return View();
        }

        [Authorize]
        [AcceptVerbs(HttpVerbs.Post)]
        public RedirectToRouteResult DeleteComment(int commentID)
        {
            IComment comment = CommentHandler.GetComment(commentID);
            if(comment != null)
                CommentHandler.RemoveComment(comment);
            return RedirectToAction("Index");
        }

        [ValidateInput(false)]  
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult AddComment(Entry entry, Comment comment, IAuthor author, bool subscribeToComments)
        {
            if (ModelState.IsValid && ValidateComment(comment, author))
            {
                comment.Author = author;
                comment = (Comment)CommentHandler.AddComment(comment);
                
                if(subscribeToComments)
                    AddCommentNotificationSubscriber(comment);

                NotifySubscribers(comment);

                return Redirect(GetCommentUrl(comment));
            }

            return View("Index", entry);
        }

        private bool ValidateComment(Comment comment, IAuthor author)
        {
            foreach (ICommentValidator validator in _commentValidators)
            {
                if (!validator.Validate(HttpContext, comment, author, ModelState))
                    return false;
            }

            return true;
        }

        private string GetCommentUrl(IComment comment)
        {
            return ((Entry)comment.CommentedEntity).GetUrl(ControllerContext.RequestContext) + "#comment" + comment.ID;
        }

        private void NotifySubscribers(IComment comment)
        {
            string commentUrl = GetCommentUrl(comment);
            foreach (ICommentAddedNotifier notifier in _commentAddedNotifiers)
            {
                notifier.Notify(comment, commentUrl);
            }
        }

        private void AddCommentNotificationSubscriber(IComment comment)
        {
            Entry commentedEntry = ((Entry)comment.CommentedEntity);
            if ((commentedEntry).GetSubscribers().Count(subscriber => subscriber != null && subscriber.Email.Equals(comment.Author.Email, StringComparison.InvariantCultureIgnoreCase)) == 0)
            {
                Entry clonedEntry = (Entry)commentedEntry.Clone();
                clonedEntry.AddSubscriber(comment.Author);
                _blogHandlerFacade.UpdateEntry(clonedEntry);
            }
        }

        [ValidateInput(false)]
        public ActionResult PreviewComment(Entry entry, string comment)
        {
            return View("CommentContent", new Comment(entry, comment, null));
        }
    }
}
